package com.shh.rabbitmq.common;

import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.StringUtils;

/***
 * 通用查询列表转换对象列表对象
 * @author shaoh
 *
 * @param <T>
 */
public class CommonMapperResultList<T> implements ResultSetExtractor<List<T>>{

	    private Class<T> clazz;
	    private Map<String,PropertyDescriptor> mappedFields;

	    public CommonMapperResultList(Class<T> clazz){
	        initialize(clazz);
	    }

	    public Class<T> getClazz() {
	        return clazz;
	    }

	    public void initialize(Class<T> clazz){
	        this.clazz = clazz;
	        this.mappedFields = new HashMap<String, PropertyDescriptor>();
	        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(clazz);
	        for (PropertyDescriptor pd : pds) {
	            if (pd.getWriteMethod() != null) {
	                this.mappedFields.put(pd.getName().toLowerCase(), pd);
	            }
	        }
	    }


	    @SuppressWarnings("deprecation")
		public List<T> extractData(ResultSet rs) throws SQLException, DataAccessException {
	        List<T> list = new ArrayList<T>();
	        Class<T> clazz = getClazz();

	        try {
	            while(rs.next()){
	                T t = BeanUtils.instantiate(clazz);
	                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(t);
	                ResultSetMetaData rsmd = rs.getMetaData();
	                int columnCount = rsmd.getColumnCount();
	                for(int i = 1;i<=columnCount;i++){
	                    String column = StringUtils.capitalize(JdbcUtils.lookupColumnName(rsmd, i));
	                    PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase());
	                    if(pd != null){Object value = JdbcUtils.getResultSetValue(rs, i, pd.getPropertyType());
	                        bw.setPropertyValue(pd.getName(),value);
	                    }
	                }
	                list.add(t);
	            }
	        } catch (IllegalArgumentException e) {
	            e.printStackTrace();
	        }
	        return list;
	    }
}
